function Course() {
  var me = this;
  me.directions = null;
  me.lineString = ge.createLineString('');
  me.lineStringPlacemark = ge.createPlacemark('');
  me.lineStringPlacemark.setGeometry(me.lineString);
  me.lineString.setTessellate(true);
  ge.getFeatures().appendChild(me.lineStringPlacemark);

  if (!me.lineStringPlacemark.getStyleSelector()) {
    me.lineStringPlacemark.setStyleSelector(ge.createStyle(''));
  }

  //var lineStyle = me.lineStringPlacemark.getStyleSelector().getLineStyle();
  //lineStyle.setWidth(lineStyle.getWidth() + 100);
  // Color is specified in 'aabbggrr' format.
  //lineStyle.getColor().set('66ff0000');

  placemarks[me.lineStringPlacemark.getName()] = me.lineStringPlacemark;

  me.start = null;
  me.finish = null;
  me.startCoord = null;
  me.finishCoord = null;
}

Course.prototype.setStart = function(loc) {
  var me = this;
  me.start = loc;
  this.generateCheckpoints();
}

Course.prototype.setFinish = function(loc) {
  var me = this;
  me.finish = loc;
  this.generateCheckpoints();
}

Course.prototype.getStartCoord = function() {
  return this.startCoord;
}

Course.prototype.getStartHeading = function() {
  if (this.directions == null) {
    return 0;
  }
  var polyline = this.directions.getPolyline();
  var count = polyline.getVertexCount();
  if (count < 2) {
    return 0;
  }
  var p1 = polyline.getVertex(0);
  var p2 = polyline.getVertex(1);
  var rise = p2.lat() - p1.lat();
  var run = p2.lng() - p1.lng();
  log("rise: " + rise + " run: " + run);
  // TODO(pmy): This should be in local coords instead of lat/lng
  if (run == 0) {
    return 180 * (rise < 0);
  } else if (rise == 0) {
    return 90 + 180 * (run < 0);
  }
  var rad = Math.atan(run / rise);
  return rad * 180 / Math.PI;
}

Course.prototype.getFinishCoord = function() {
  return this.finishCoord;
}

Course.prototype.generateCheckpoints = function() {
  var me = this;
  if (this.start != null && this.finish != null) {
    me.directions = new google.maps.Directions(null, null);
    google.maps.Event.addListener(me.directions, 'load',
      function() {
        // Directions data has loaded
        var polyline = me.directions.getPolyline();
        var numVertices = polyline.getVertexCount();

        me.startCoord = polyline.getVertex(0);
        if (racecar != null) {
          log('moving racecar: '+ me.startCoord);
          racecar.moveToPos(me.startCoord.lat(), me.startCoord.lng(), 0);
        } else {
          log('racecar is null!');
        }
        me.finishCoord = polyline.getVertex(numVertices-1);
        createPlacemark('Start', 'Start', me.startCoord.lat(), me.startCoord.lng());
        createPlacemark('Finish', 'Finish', me.finishCoord.lat(), me.finishCoord.lng());
        var coords = me.lineString.getCoordinates();
        coords.clear();
        for (var i = 0; i < numVertices; i++) {
          var vertex = polyline.getVertex(i);
          log('added ' + vertex.lat()+ ',' + vertex.lng());
          coords.pushLatLngAlt(vertex.lat(), vertex.lng(), 0);
        }
      }
    );
    me.directions.load('from: ' + this.start + ' to: ' + this.finish, {getSteps: true, getPolyline: true});
  }
}
